#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define lc (o<<1)
#define rc (o<<1|1)
#define mid ((l+r)>>1)
using namespace std;
typedef long long LL;
typedef double db;
inline int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9') { if(ch=='-')f=-1; ch=getchar(); }
	while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+ch-'0'; ch=getchar(); }
	return x*f;
}
const int MAXN=1e5+10;
int n,m;
struct Seg_T
{
	int sumv[2][MAXN<<2],lmax[2][MAXN<<2],rmax[2][MAXN<<2],mmax[2][MAXN<<2],covv[MAXN<<2];
	bool tun[MAXN<<2];
	inline void push_up(int o,int l,int r)
	{
		for(int i=0;i<=1;++i)
		{
			sumv[i][o]=sumv[i][lc]+sumv[i][rc];
			lmax[i][o]=lmax[i][lc]==mid-l+1?mid-l+1+lmax[i][rc]:lmax[i][lc];
			rmax[i][o]=rmax[i][rc]==r-mid?r-mid+rmax[i][lc]:rmax[i][rc];
			mmax[i][o]=max(max(mmax[i][lc],mmax[i][rc]),rmax[i][lc]+lmax[i][rc]);
		}
		return;
	}
	inline void cover(int o,int x,int l,int r)
	{
		int y=!x;
		sumv[x][o]=lmax[x][o]=rmax[x][o]=mmax[x][o]=r-l+1;
		sumv[y][o]=lmax[y][o]=rmax[y][o]=mmax[y][o]=0;
		covv[o]=x;tun[o]=false;
		return;
	}
	inline void turn(int o,int l,int r)
	{
		if(~covv[o])cover(o,!covv[o],l,r);
		else
		{
			swap(lmax[0][o],lmax[1][o]);
			swap(rmax[0][o],rmax[1][o]);
			swap(mmax[0][o],mmax[1][o]);
			swap(sumv[0][o],sumv[1][o]);
			tun[o]^=1;
		}
		return;
	}
	inline void push_down(int o,int l,int r)
	{
		if(~covv[o])
		{
			cover(lc,covv[o],l,mid);
			cover(rc,covv[o],mid+1,r);
			covv[o]=-1;
		}
		if(tun[o])
		{
			turn(lc,l,mid);
			turn(rc,mid+1,r);
			tun[o]=false;
		}
		return;
	}
	void build(int o,int l,int r)
	{
		covv[o]=-1;
		if(l==r)
		{
			int x=read();
			sumv[x][o]=lmax[x][o]=rmax[x][o]=mmax[x][o]=1;
			return;
		}
		build(lc,l,mid);
		build(rc,mid+1,r);
		push_up(o,l,r);
		return;
	}
	void update(int o,int l,int r,int yl,int yr,int k)
	{
		if(yl<=l&&r<=yr)
		{
			if(k<2)cover(o,k,l,r);
			else turn(o,l,r);
			return;
		}
		push_down(o,l,r);
		if(yl<=mid)update(lc,l,mid,yl,yr,k);
		if(yr>mid)update(rc,mid+1,r,yl,yr,k);
		push_up(o,l,r);
		return;
	}
	int query_sum(int o,int l,int r,int yl,int yr)
	{
		if(yl<=l&&r<=yr)return sumv[1][o];
		int ret=0;
		push_down(o,l,r);
		if(yl<=mid)ret=query_sum(lc,l,mid,yl,yr);
		if(yr>mid)ret+=query_sum(rc,mid+1,r,yl,yr);
		return ret;
	}
	void query_max(int o,int l,int r,int yl,int yr,int &ansl,int &ansm,int &ansr)
	{
		if(yl<=l&&r<=yr)
		{
			ansl=lmax[1][o];
			ansm=mmax[1][o];
			ansr=rmax[1][o];
			return;
		}
		push_down(o,l,r);
		if(yr<=mid)return query_max(lc,l,mid,yl,yr,ansl,ansm,ansr);
		else if(yl>mid)return query_max(rc,mid+1,r,yl,yr,ansl,ansm,ansr);
		else
		{
			int l1,l2,r1,r2,m1,m2;
			query_max(lc,l,mid,yl,yr,l1,m1,r1);
			query_max(rc,mid+1,r,yl,yr,l2,m2,r2);
			ansl=l1==mid-l+1?mid-l+1+l2:l1;
			ansr=r2==r-mid?r-mid+r1:r2;
			ansm=max(max(m1,m2),r1+l2);
		}
		return;
	}
}T1;
int main()
{
#ifndef ONLINE_JUDGE
	freopen("in.in","r",stdin);
	freopen("out.out","w",stdout);
#endif
	n=read();m=read();
	T1.build(1,1,n);
	while(m--)
	{
		int op=read(),x=read()+1,y=read()+1;
		if(op<3)T1.update(1,1,n,x,y,op);
		else if(op==3)printf("%d\n",T1.query_sum(1,1,n,x,y));
		else 
		{
			int t1,t2,t3;
			T1.query_max(1,1,n,x,y,t1,t2,t3);
			printf("%d\n",max(t1,max(t2,t3)));
		}
	}
	return 0;
}
